#pragma once
#include "SceneData.hpp"
#include <Utility/IOObject.hpp>

namespace zzz {
typedef SceneDataf64::Point2D SceneDataf32Point2D;
SIMPLE_IOOBJECT(SceneDataf32Point2D);

typedef SceneDataf64::Point SceneDataf32Point;
template<>
class IOObject<SceneDataf32Point> {
public:
  typedef SceneDataf32Point DataType;
  static const int RF_POS3D = 1;
  static const int RF_POS2DS = 2;
  static const int RF_FERROR = 3;
  static const int RF_PERROR = 4;
  static const int RF_STATUS = 5;
  static void WriteFileR(RecordFile &rf, const DataType &src) {
    IOObj::WriteFileR(rf, RF_POS3D, src.pos3d);
    IOObj::WriteFileR(rf, RF_POS2DS, src.pos2ds);
    IOObj::WriteFileR(rf, RF_FERROR, src.ferror);
    IOObj::WriteFileR(rf, RF_PERROR, src.perror);
    IOObj::WriteFileR(rf, RF_STATUS, src.status);
  }
  static void ReadFileR(RecordFile &rf, DataType &dst) {
    IOObj::ReadFileR(rf, RF_POS3D, dst.pos3d);
    IOObj::ReadFileR(rf, RF_POS2DS, dst.pos2ds);
    IOObj::ReadFileR(rf, RF_FERROR, dst.ferror);
    IOObj::ReadFileR(rf, RF_PERROR, dst.perror);
    IOObj::ReadFileR(rf, RF_STATUS, dst.status);
  }
};

typedef SceneDataf64::ImageInfo SceneDataf32ImageInfo;
SIMPLE_IOOBJECT(SceneDataf32ImageInfo);

typedef SceneDataf64::CameraInfo SceneDataf32CameraInfo;
SIMPLE_IOOBJECT(SceneDataf32CameraInfo);

typedef SceneDataf64::SIFTMatch SceneDataf32SIFTMatch;
SIMPLE_IOOBJECT(SceneDataf32SIFTMatch::PtIdx);
SIMPLE_IOOBJECT(SceneDataf32SIFTMatch::Matches);
template<>
class IOObject<SceneDataf32SIFTMatch> {
public:
  typedef SceneDataf32SIFTMatch DataType;
  static const int RF_ID1 = 1;
  static const int RF_ID2 = 2;
  static const int RF_PTIDX = 3;
  static const int RF_MATCHES = 4;
  static void WriteFileR(RecordFile &rf, const DataType &src) {
    IOObj::WriteFileR(rf, RF_ID1, src.id1);
    IOObj::WriteFileR(rf, RF_ID2, src.id2);
    IOObj::WriteFileR(rf, RF_PTIDX, src.ptidx);
    IOObj::WriteFileR(rf, RF_MATCHES, src.matches);
  }
  static void ReadFileR(RecordFile &rf, DataType &dst) {
    IOObj::ReadFileR(rf, RF_ID1, dst.id1);
    IOObj::ReadFileR(rf, RF_ID2, dst.id2);
    IOObj::ReadFileR(rf, RF_PTIDX, dst.ptidx);
    IOObj::ReadFileR(rf, RF_MATCHES, dst.matches);
  }
};

typedef SceneDataf64::SfMPair SceneDataf32SfMPair;
SIMPLE_IOOBJECT(SceneDataf32SfMPair);

template<>
class IOObject<SceneDataf64> {
public:
  typedef SceneDataf64 DataType;
  static const int RF_POINTS = 1;
  static const int RF_IMGINFOS = 2;
  static const int RF_CAMERAS = 3;
  static const int RF_SIFTKEYS = 4;
  static const int RF_SIFTMATCHES = 5;
  static const int RF_SFMPAIR = 6;

  static void WriteFileR(RecordFile &rf, const zint32 label, const SceneData<zfloat32> &src) {
    IOObj::WriteFileR1By1(rf, RF_POINTS, src.points_);
    IOObj::WriteFileR(rf, RF_IMGINFOS, src.imginfos_);
    IOObj::WriteFileR(rf, RF_CAMERAS, src.cameras_);
    IOObj::WriteFileR1By1(rf, RF_SIFTKEYS, src.siftkeys_);
    IOObj::WriteFileR1By1(rf, RF_SIFTMATCHES, src.siftmatches_);
    IOObj::WriteFileR(rf, RF_SFMPAIR, src.sfmpairs_);
  }

  static void ReadFileR(RecordFile &rf, const zint32 label, SceneData<zfloat32> &dst) {
    IOObj::ReadFileR1By1(rf, RF_POINTS, dst.points_);
    IOObj::ReadFileR(rf, RF_IMGINFOS, dst.imginfos_);
    IOObj::ReadFileR(rf, RF_CAMERAS, dst.cameras_);
    IOObj::ReadFileR1By1(rf, RF_SIFTKEYS, dst.siftkeys_);
    IOObj::ReadFileR1By1(rf, RF_SIFTMATCHES, dst.siftmatches_);
    IOObj::ReadFileR(rf, RF_SFMPAIR, dst.sfmpairs_);
  }
};
};  // namespace zzz